<template>
  <div class="atom-content" v-loading="loading">
    <div class="header">
      <el-row :gutter="20">
        <el-col :span="6" align="left">
          <div class="factory-top">
            <icon-svg name="iconKpi"></icon-svg>
            原子指标
          </div>
        </el-col>
        <el-col :span="18" align="right">
          <div class="btns">
            <el-button @click="handleReject">
              <icon-svg name="iconCancel"></icon-svg>
              取消
            </el-button>
            <el-button type="primary" @click="handlePreview">
              <icon-svg name="iconFacEye"></icon-svg>
              预览
            </el-button>
            <el-button type="primary" @click="handleSave">
              <icon-svg name="iconSave"></icon-svg>
              保存
            </el-button>
          </div>
        </el-col>
      </el-row>
    </div>
    <div class="kpi-content">
      <div class="kpi-preview">
        <h4>公式预览</h4>
        <atom-logic :dataLabs="editForm.dataLabs"></atom-logic>
      </div>
      <div class="kpi-logical">
        <ul class="clearfix">
          <li
            v-for="item in logicalList"
            :key="item.funcId"
            @click="addItem(Object.assign({}, item, { type_id: '0' }))"
          >
            {{ item.showOperator }}
          </li>
          <li @click="handleDelete"><icon-svg name="iconDelete"></icon-svg></li>
        </ul>
      </div>
      <div class="kpi-canvas" @drop="copyDrop($event)" @dragover="allowDrag($event)">
        <el-form :model="editForm" ref="editForm" label-width="0" v-if="this.editForm.dataLabs.length">
          <ul>
            <li
              v-for="(item, index) in editForm.dataLabs"
              :key="index"
              class="data-item"
              :index="index"
              :class="{ 'logic-item': item.type_id == '0' }"
            >
              <atom-content-item
                v-if="item.type_id == '2'"
                :config="item"
                :parentIndex="index"
                :formProp="'dataLabs.' + index"
                @dragstart="copyDrag($event, item, index)"
              ></atom-content-item>
              <div class="item-content" draggable @dragstart="copyDrag($event, item, index)" v-else>
                {{ item.type_id == '1' ? item.lab_column : item.showOperator || item.symbol }}
              </div>
            </li>
          </ul>
        </el-form>
        <div class="config-tips" v-else>
          <span>
            <i class="el-icon-plus"></i>
          </span>
          <br />
          将字段或公式拖入此区域
        </div>
        <div class="canvas-handler delete-area">
          <icon-svg name="iconDelete" class="delete-area"></icon-svg><br />拖至此处删除
        </div>
      </div>
    </div>
    <atom-drawer ref="atomDrawer" @callback="confirm"></atom-drawer>
  </div>
</template>

<script>
import atomLogic from './atom-logic'
import atomContentItem from './atom-content-item'
import atomDrawer from './atom-drawer'
import cloneDeep from 'lodash/cloneDeep'
export default {
  props: {
    logicalList: {
      type: Array,
      require: true,
      default: () => []
    }
  },
  components: {
    atomLogic,
    atomContentItem,
    atomDrawer
  },
  data() {
    return {
      loading: false,
      previewLabs: [],
      oldConfig: {},
      editForm: {
        groupId: '',
        tagId: '',
        tagNm: '',
        tableNm: '',
        unitMeasure: '',
        execFrequency: '',
        execTm: '',
        execWkList: [],
        execDtList: [],
        tagStory: '',
        valueType: '',
        dataLabs: [],
        results: []
      }
    }
  },
  methods: {
    init() {
      this.$nextTick(() => {
        if (this.$route.query.tagId) {
          this.editForm.tagId = this.$route.query.tagId
          this.getDetail()
        }
        if (this.$route.query.groupId) this.editForm.groupId = this.$route.query.groupId
      })
    },
    getDetail() {
      this.$ajax({
        url: this.$ajax.setUrl(`IndexAllocation/getIndexAtomic/${this.editForm.tagId}`),
        method: 'get',
        params: this.$ajax.setParams()
      }).then(({ data }) => {
        if (data && data.code === '0') {
          this.oldConfig = cloneDeep(data.data)
          this.previewLabs = cloneDeep(JSON.parse(data.data.tagConfigJson))
          this.editForm.tagNm = data.data.tagNm
          this.editForm.tableNm = data.data.tableNm
          this.editForm.execFrequency = data.data.execFrequency
          this.editForm.execTm = data.data.execTm
          this.editForm.execWkList = JSON.parse(data.data.execWkList)
          this.editForm.execDtList = JSON.parse(data.data.execDtList)
          this.editForm.tagStory = data.data.tagStory
          this.editForm.valueType = data.data.valueType
          this.editForm.unitMeasure = data.data.unitMeasure
          this.editForm.dataLabs = JSON.parse(data.data.tagConfigJson)
          this.editForm.results = JSON.parse(data.data.previewResults)
          this.$parent.updateTable(data.data.tableNm)
        } else {
          this.$message.error(data.data || data.msg)
        }
      })
    },
    allowDrag(event) {
      event.preventDefault()
    },
    copyDrag(event, item, index) {
      event.dataTransfer.setData('drag_type', 'delete')
      event.dataTransfer.setData('index', index)
      event.dataTransfer.setData('type_id', item.type_id)
      if (item.type_id == '1') {
        event.dataTransfer.setData('labTbl', item.lab_table)
        event.dataTransfer.setData('labFldMap', item.lab_column)
      } else if (item.type_id == '2') {
        event.dataTransfer.setData('func_config', JSON.stringify(item))
      } else {
        event.dataTransfer.setData('operator', item.symbol)
        event.dataTransfer.setData('showOperator', item.showOperator)
      }
    },
    copyDrop(event) {
      let target = event.target
      const type_id = event.dataTransfer.getData('type_id')
      const drag_type = event.dataTransfer.getData('drag_type')
      const labFldMap = event.dataTransfer.getData('labFldMap')
      let isDelete = target.className && target.className.includes('delete-area')
      if (drag_type === 'delete' && isDelete) {
        const index = event.dataTransfer.getData('index')
        this.editForm.dataLabs.splice(index, 1)
      } else {
        const oldIndex = event.dataTransfer.getData('index')
        let nodes = []
        let index = -1
        while (target.className !== 'kpi-canvas') {
          nodes.push(target)
          if (target.className && target.className.includes('data-item')) {
            index = parseInt(target.getAttribute('index'))
          }
          target = target.parentNode
        }
        if (drag_type === 'delete') {
          if (index < 0) return
          // 先把旧数据删掉
          this.editForm.dataLabs.splice(oldIndex, 1)
          if (index > oldIndex) index--
        }
        if (labFldMap && nodes.find(nodeTarget => nodeTarget.className && nodeTarget.className.includes('func-tag'))) {
          // 将标签拖入到函数里面
          const func_tag = nodes.find(nodeTarget => nodeTarget.className.includes('func-tag'))
          const func_index = parseInt(func_tag.getAttribute('index'))
          const labTbl = event.dataTransfer.getData('labTbl')
          this.editForm.dataLabs[index].func_param.param[func_index].param.lab_table = labTbl
          this.editForm.dataLabs[index].func_param.param[func_index].param.lab_column = labFldMap
        } else {
          if (labFldMap) {
            // 拖入标签
            const labTbl = event.dataTransfer.getData('labTbl')
            this.addItem({ labTbl, labFldMap, type_id: type_id || '1' }, index)
          } else {
            if (type_id == '2') {
              // 函数
              const func_config = JSON.parse(event.dataTransfer.getData('func_config'))
              this.addItem({ type_id, ...func_config }, index)
            } else {
              // 公式
              const operator = event.dataTransfer.getData('operator')
              const showOperator = event.dataTransfer.getData('showOperator')
              this.addItem({ operator, showOperator, type_id: type_id }, index)
            }
          }
        }
      }
    },
    addItem(item, index = -1) {
      let params = {}
      if (item.type_id == '1') {
        // 标签
        // const target = this.$parent.tableList.find(table => table.tableNm === this.$parent.selectTable)
        params = {
          type_id: item.type_id,
          tag_id: '',
          tag_nm: '',
          lab_table: `${item.labTbl}`,
          lab_column: item.labFldMap,
          symbol: '',
          func_param: {}
        }
      } else if (item.type_id == '0') {
        // 符号
        params = {
          type_id: item.type_id,
          symbol: item.operator,
          showOperator: item.showOperator,
          tag_nm: '',
          lab_table: '',
          lab_column: '',
          func_param: {}
        }
      } else if (item.type_id == '2') {
        params = {
          type_id: item.type_id,
          symbol: '',
          lab_table: '',
          lab_column: '',
          func_param: {
            func_id: item.funcId || item.func_param.func_id,
            func_name: item.funcIdentifier || item.func_param.func_name,
            param: []
          }
        }
        const selectList = item.funcParam || item.func_param.param
        selectList.forEach(func => {
          params.func_param.param.push({
            type_id: func.type_id,
            param: {
              tag_nm: '',
              lab_table: '',
              lab_column: '',
              constant: '',
              company: '',
              show_company: '',
              company_list: func.identifier_name || func.param.company_list
            }
          })
        })
      }
      if (index < 0 || index >= this.editForm.dataLabs.length) this.editForm.dataLabs.push(params)
      else this.editForm.dataLabs.splice(index + 1, 0, params)
    },
    handleDelete() {
      if (this.editForm.dataLabs.length) this.deleteItem(this.editForm.dataLabs.length - 1)
    },
    deleteItem(index) {
      this.editForm.dataLabs.splice(index, 1)
    },
    handlePreview() {
      if (!this.editForm.dataLabs.length) {
        this.$message.info('请添加指标配置！')
        return
      }
      this.$refs.editForm.validate(valid => {
        if (valid) {
          this.$ajax({
            url: this.$ajax.setUrl('IndexAllocation/showAtomicIndex'),
            method: 'post',
            data: this.$ajax.setData({
              tableNm: this.$parent.selectTable,
              tagConfigJson: JSON.stringify(this.editForm.dataLabs)
            })
          }).then(({ data }) => {
            if (data && data.code === '0') {
              this.editForm.results = data.data.previewResults
              this.previewLabs = cloneDeep(this.editForm.dataLabs)
              this.$message.success(data.msg)
            } else {
              this.$message.error(data.data || data.msg)
            }
          })
        }
      })
    },
    handleSave() {
      if (!this.editForm.dataLabs.length) {
        this.$message.info('请添加指标配置！')
        return
      }
      let previewLabs = cloneDeep(this.previewLabs)
      if (!this.$utils.compareArray(this.editForm.dataLabs, previewLabs)) {
        this.$message.info('指标配置有变化，请先预览再保存！')
        return
      }
      const params = {
        tagId: this.editForm.tagId,
        tagNm: this.editForm.tagNm,
        execFrequency: this.editForm.execFrequency,
        execTm: this.editForm.execTm,
        execWkList: this.editForm.execWkList,
        execDtList: this.editForm.execDtList,
        tagStory: this.editForm.tagStory,
        valueType: this.editForm.valueType,
        unitMeasure: this.editForm.unitMeasure,
        dataLabs: this.editForm.dataLabs,
        tableNm: this.$parent.selectTable,
        results: this.editForm.results
      }
      if (this.editForm.groupId) params.groupId = this.editForm.groupId
      this.$refs.editForm.validate(valid => {
        if (valid) {
          this.$refs.atomDrawer.showDrawer(params)
        }
      })
    },
    confirm(params) {
      this.editForm.tagId = params.tagId
      this.editForm.tagNm = params.tagNm
      this.editForm.execFrequency = params.execFrequency
      this.editForm.execTm = params.execTm
      this.editForm.execWkList = params.execWkList
      this.editForm.execDtList = params.execDtList
      this.editForm.tagStory = params.tagStory
      this.editForm.valueType = params.valueType
      this.editForm.unitMeasure = params.unitMeasure
      let config = cloneDeep(this.oldConfig)
      this.oldConfig = Object.assign({}, config, { tagConfigJson: this.editForm.dataLabs }, params)
    },
    handleReject() {
      this.$confirm('确定取消最新的编辑？').then(() => {
        if (this.editForm.tagId) {
          const config = cloneDeep(this.oldConfig)
          this.editForm.tagNm = config.tagNm
          this.editForm.tagStory = config.tagStory
          this.editForm.valueType = config.valueType
          this.editForm.dataLabs =
            typeof config.tagConfigJson == 'string' ? JSON.parse(config.tagConfigJson) : config.tagConfigJson
          this.editForm.results = config.previewResults
        } else {
          this.editForm.tagNm = ''
          this.editForm.tagStory = ''
          this.editForm.valueType = ''
          this.editForm.dataLabs = []
          this.editForm.results = []
        }
        this.$forceUpdate()
      })
    }
  }
}
</script>

<style lang="scss">
.atom-content {
  margin-left: 650px;
  padding-right: 10px;
  height: 100%;
  .header {
    height: 50px;
    overflow: hidden;
  }
  .factory-top {
    font-size: 17px;
    font-weight: bold;
    margin-top: 15px;
    svg {
      width: 30px;
      height: 30px;
      color: $theme-color;
      margin: -5px 5px 0 0;
      vertical-align: middle;
    }
  }
  .btns {
    text-align: right;
    .el-button {
      margin-top: 9px;
    }
    .el-button {
      font-size: 15px;
      color: #455fbc;
      background-color: transparent;
      border-color: transparent;
      svg {
        font-size: 20px;
        width: 20px;
        height: 20px;
        margin-right: 3px;
        margin-top: -5px;
        vertical-align: middle;
        // color: #455fbc;
      }
      & + .el-button {
        margin-left: 0;
      }
      &.disabled {
        color: #999;
      }
    }
    .el-input--prefix {
      .el-input__inner {
        height: 35px;
        color: #455fbc;
        border-color: #455fbc;
      }
      .el-input__icon {
        color: #455fbc;
      }
      .el-input__prefix,
      .el-input__suffix {
        top: -3px;
      }
    }
  }
  .kpi-content {
    height: calc(100% - 50px);
    padding-right: 20px;
    border: 1px solid #ddd;
    overflow-y: auto;
    .kpi-canvas .config-tips {
      width: 400px;
      height: 300px;
      color: #999;
      text-align: center;
      position: absolute;
      top: calc(50% - 50px);
      left: 50%;
      transform: translate(-50%, -50%);
      span {
        display: inline-block;
        width: 30px;
        height: 30px;
        line-height: 30px;
        border: 2px solid #999;
        text-align: center;
        margin-right: 10px;
        border-radius: 5px;
        margin: 100px 0 20px 0;
        i {
          font-size: 20px;
          font-weight: bold;
        }
      }
    }
  }
  .kpi-preview {
    padding: 10px 20px;
    h4 {
      color: #666;
    }
  }
  .kpi-logical {
    padding: 10px 20px;
    border-top: 1px solid #ddd;
    background-color: #f0f4f7;
    li {
      display: inline-block;
      font-size: 20px;
      font-weight: bold;
      width: 40px;
      height: 40px;
      text-align: center;
      line-height: 40px;
      margin-right: 20px;
      color: #fff;
      background-color: #6a86cc;
      border-radius: 4px;
      cursor: pointer;
      &:last-child {
        float: right;
        background-color: #ff7272;
        margin-right: 0;
      }
    }
  }
  .kpi-canvas {
    height: calc(100% - 262px);
    padding: 20px;
    position: relative;
    .canvas-handler {
      height: 100px;
      color: #666;
      margin: 12px;
      background-color: #fafafa;
      border: 1px dashed #ddd;
      text-align: center;
      opacity: 0.6;
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      transition: all 0.2s linear;
      svg {
        width: 30px;
        height: 30px;
        margin: 20px 0 10px 0;
        color: #ff7272;
      }
      &:hover {
        opacity: 1;
        background-color: #f0f4f7;
      }
    }
    .data-item {
      display: inline-block;
      margin: 20px;
      position: relative;
      cursor: pointer;
      &::before {
        content: '';
        background-color: #e6eeff;
        position: absolute;
        top: -6px;
        right: -6px;
        bottom: -6px;
        left: -6px;
        border-radius: 4px;
      }
      .item-content {
        font-weight: bold;
        padding: 10px 50px;
        background-color: #fff;
        border: 1px dashed #c0d5ff;
        position: relative;
        z-index: 2;
        border-radius: 4px;
      }
      .func-item {
        padding: 0;
        border: 0;
        background-color: #e6eeff;
      }
      .func-tag {
        min-width: 100px;
        padding: 3px 10px;
        border: 1px dashed #c0d5ff;
        background-color: #fff;
      }
      .func-tag,
      .func-num {
        display: inline-block;
        margin-left: 15px;
        text-align: center;
        .el-form-item {
          margin-bottom: 0;
          background-color: #fff;
        }
        .el-form-item__content {
          line-height: 30px;
        }
        .el-input {
          margin: 0;
          padding: 0;
        }
        .el-input__inner {
          text-align: center;
        }
        .el-input__suffix {
          top: 0;
          right: 5px;
        }
      }
      .func-name {
        display: inline-block;
        padding: 10px;
        color: #fff;
        background-color: #4d81ea;
        border-radius: 3px;
      }
      .el-form-item__error {
        margin-top: 10px;
      }
    }
    .logic-item {
      &::before {
        background-color: #fff0e9;
      }
      .item-content {
        width: 38px;
        height: 38px;
        text-align: center;
        line-height: 35px;
        padding: 0;
        color: #fff;
        background-color: #ff9c6c;
        border-color: #ff9c6c;
      }
    }
  }
}
</style>
